﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using Outlook = Microsoft.Office.Interop.Outlook;
using Office = Microsoft.Office.Core;
using System.Threading;
using Investafinance.Sync.Shell;

namespace OutlookAddIn_Collaboratori
{
    // wb Ribbon http://msdn.microsoft.com/ru-ru/library/bb226712(en-us,printer).aspx

    public partial class ThisAddIn
    {
        private Outlook.Inspectors m_Inspectors;          // Outlook inspectors collection
        internal static List<OutlookInspector> m_Windows; // List of tracked inspector windows

        // строка конекта к бызе данных
        private string scon = @"Data Source=|DataDirectory|\Meta.sdf";

        //Кнопка на меню "Синхронизация"
        private List<Office.CommandBarButton> MyButtonSync = new List<Office.CommandBarButton> ();
        private Office.CommandBarButton MyButtonUser = null;

        private Microsoft.Office.Interop.Outlook.NameSpace m_NameSapace;



        public static AddinSattings sattings;//= new AddinSattings(@"c:\config.txt");


        private List<Investafinance.Sync.Shell.ShellFolderSync<Outlook.ContactItem>> wFolderContact =
            new List<Investafinance.Sync.Shell.ShellFolderSync<Outlook.ContactItem>>();

        private List<Investafinance.Sync.Shell.ShellFolderSync<Outlook.TaskItem>> wFolderTask = 
            new List<Investafinance.Sync.Shell.ShellFolderSync<Outlook.TaskItem>>();


        static public string[,] associateMap;

        Investafinance.Credential Credential;
        private string PathConfig;


        #region ThisAddIn_Startup
        private void ThisAddIn_Startup(object sender, System.EventArgs e)
        {
            

            System.Data.SqlServerCe.SqlCeConnection con = new System.Data.SqlServerCe.SqlCeConnection(scon);
            con.Open();
            string s =  con.Database.Remove(con.Database.IndexOf(@"\Meta.sdf"));            
            con.Close();
            s =  s + @"\config.txt.sdf";
            PathConfig = s;
            sattings = new AddinSattings(@"d:\config.txt");//s);



            m_NameSapace = this.Application.Session;


            m_NameSapace.Application.OptionsPagesAdd += new Microsoft.Office.Interop.Outlook.ApplicationEvents_11_OptionsPagesAddEventHandler(OptionsPages);

            m_Inspectors = this.Application.Inspectors;
            m_Windows = new List<OutlookInspector>();

            // обработчик события - создание нового окна
            m_Inspectors.NewInspector +=
                new Outlook.InspectorsEvents_NewInspectorEventHandler(Inspectors_NewInspector);

            Credential = new Investafinance.Credential(sattings.Password, sattings.Domian, sattings.UserName);
            sattings.EventUpdateCreditional += UpdateCreditional;
          
            //прикрепляем всех необходимых делигатов ко всем синхронизированным папкам
            for (int i = 0; i < sattings.Folders.Count; i++)
            {
                if (sattings.Folders[i].DefaultMessageClass == "IPM.Contact")
                    wFolderContact.Add(new ShellFolderSync<Outlook.ContactItem>(scon,sattings.Folders[i].ListName,sattings.Folders[i].NameFolder,
                                                                      Outlook.OlDefaultFolders.olFolderContacts,
                                                                      sattings.Folders[i].collectionField, Globals.ThisAddIn.Application,sattings.Folders[i].MessageClass, 
                                                                      sattings.Folders[i].Url, sattings.Folders[i].ListName,
                                                                      ref Credential));
                else
                if (sattings.Folders[i].DefaultMessageClass == "IPM.Task")
                    wFolderTask.Add(new ShellFolderSync<Outlook.TaskItem>(scon,sattings.Folders[i].ListName,sattings.Folders[i].NameFolder,
                                                                      Outlook.OlDefaultFolders.olFolderTasks,
                                                                      sattings.Folders[i].collectionField, Globals.ThisAddIn.Application,sattings.Folders[i].MessageClass,
                                                                      sattings.Folders[i].Url, sattings.Folders[i].ListName,
                                                                      ref Credential));
            }

            //???
            for (int i = 0; i < sattings.Folders.Count; i++)
                if (sattings.Folders[i].ListName == "collaboratori")
                {
                    associateMap = sattings.Folders[i].collectionField;
                }


            //Создадим кнопку на понели Синхронизация
            Office.CommandBar bar = Globals.ThisAddIn.Application.ActiveExplorer().CommandBars["Menu Bar"];
            try
            {
                Office.CommandBarPopup popup = (Office.CommandBarPopup)bar.Controls["Синхронизация"];
                popup.Delete(null);
                Office.CommandBarControl cmdBarControl = bar.Controls.Add(Office.MsoControlType.msoControlPopup, System.Reflection.Missing.Value, System.Reflection.Missing.Value, System.Reflection.Missing.Value, System.Reflection.Missing.Value);
                cmdBarControl.Visible = true;
                cmdBarControl.Caption = "Синхронизация";
                popup = (Office.CommandBarPopup)cmdBarControl;
                Office.CommandBar newbar = popup.CommandBar;

                for (int i = 0; i < sattings.Folders.Count; i++)
                {
                    MyButtonSync.Add((Office.CommandBarButton)newbar.Controls.Add(1, 1, "", 1, true));
                    MyButtonSync[i].Visible = true;
                    MyButtonSync[i].Caption = sattings.Folders[i].NameFolder;
                }

                MyButtonUser = (Office.CommandBarButton)newbar.Controls.Add(1, 1, "", 1, true);
                MyButtonUser.Visible = true;
                MyButtonUser.Caption = "User";

            }
            catch (Exception)
            {
                Office.CommandBarControl cmdBarControl = bar.Controls.Add(Office.MsoControlType.msoControlPopup, System.Reflection.Missing.Value, System.Reflection.Missing.Value, System.Reflection.Missing.Value, System.Reflection.Missing.Value);
                cmdBarControl.Visible = true;
                cmdBarControl.Caption = "Синхронизация";
                Office.CommandBarPopup popup = (Office.CommandBarPopup)cmdBarControl;
                Office.CommandBar newbar = popup.CommandBar;

                for (int i = 0; i < sattings.Folders.Count; i++)
                {
                    MyButtonSync.Add((Office.CommandBarButton)newbar.Controls.Add(1, 1, "", 1, true));
                    MyButtonSync[i].Visible = true;
                    MyButtonSync[i].Caption = sattings.Folders[i].NameFolder;
                }

                MyButtonUser = (Office.CommandBarButton)newbar.Controls.Add(1, 1, "", 1, true);
                MyButtonUser.Visible = true;
                MyButtonUser.Caption = "User";
            }
            for (int i = 0; i < sattings.Folders.Count; i++)
            {
                MyButtonSync[i].Click += new Office._CommandBarButtonEvents_ClickEventHandler(ButtonSyncClick);
            }

            MyButtonUser.Click += new Office._CommandBarButtonEvents_ClickEventHandler(ButtonUserClick);
        }
        #endregion


        #region ButtonUserClick
        private void ButtonUserClick(Microsoft.Office.Core.CommandBarButton Ctrl, ref bool CancelDefault)
        {
            if (sattings != null)
            {
                User formUser = new User(sattings);
                formUser.ShowDialog();  
            }
        }
        #endregion

        #region ButtonSyncClick
        private Thread potokSync = null;
        private void ButtonSyncClick(Microsoft.Office.Core.CommandBarButton Ctrl, ref bool CancelDefault)
        {
            if (potokSync == null)
            {
                FolderSattings folderSattings = null;
                // выясним на какую кнопку именно мы нажали 
                // тоесть найдём имя папки которуюбудем синхронизировать
                for (int i = 0; i < sattings.Folders.Count; i++)
                {
                    if (sattings.Folders[i].NameFolder == Ctrl.Caption)
                    {
                        folderSattings = sattings.Folders[i];
                        // прекратим искать
                        break;
                    }
                }


                if (folderSattings.DefaultMessageClass == "IPM.Contact")
                {
                    // найдём папку по имени которую будем синхронизировать
                    for (int i = 0; i < wFolderContact.Count; i++)
                    {
                        if (wFolderContact[i].NameFolder == Ctrl.Caption)
                        {
                            FolderContacts = wFolderContact[i];
                            if (FolderContacts.ShearchFolderORAdd())
                            {
                                // переключимся на папку которую будем синхранизировать
                                Globals.ThisAddIn.Application.ActiveExplorer().SelectFolder(FolderContacts.MapiFolder);
                                // в отдельном потоке начнём синхронизировать найдкный FolderContacts
                                potokSync = new Thread(SyncContact);
                                potokSync.Start();
                            }
                            // прекратим искать
                            break;
                        }//if

                    }//for
                  
                }
                else
                if (folderSattings.DefaultMessageClass == "IPM.Task")
                {
                    // найдём папку по имени которую будем синхронизировать
                    for (int i = 0; i < wFolderTask.Count; i++)
                    {
                        if (wFolderTask[i].NameFolder == Ctrl.Caption)
                        {
                            FolderTasks = wFolderTask[i];
                            if (FolderTasks.ShearchFolderORAdd())
                            {
                                // переключимся на папку которую будем синхранизировать
                                Globals.ThisAddIn.Application.ActiveExplorer().SelectFolder(FolderTasks.MapiFolder);//(CollaboratoreFolder);
                                // в отдельном потоке начнём синхронизировать найдкный FolderContacts
                                potokSync = new Thread(SyncTasks);
                                potokSync.Start();
                            }
                            // прекратим искать
                            break;
                        }//if

                    }//for

                }//if
            }
        }


        ShellFolderSync<Outlook.ContactItem> FolderContacts;
        private void SyncContact()
        {
            FolderContacts.Sync();
            
            potokSync = null;
            FolderContacts = null;
          
        }

        ShellFolderSync<Outlook.TaskItem> FolderTasks;
        private void SyncTasks()
        {
            FolderTasks.Sync();
            
            potokSync = null;
            FolderTasks = null;

        }

        #endregion     

        #region ThisAddIn_Shutdown
        private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
        {
            // Unhook event handlers
            m_Inspectors.NewInspector -= new Microsoft.Office.Interop.Outlook.InspectorsEvents_NewInspectorEventHandler(Inspectors_NewInspector);

            // Dereference objects
            m_Inspectors = null;
            m_Windows.Clear();
            m_Windows = null;

        }
        #endregion

        #region UpdateCreditional событие возникает при редактировании Creditional в sattings.EventUpdateCreditional
        private void UpdateCreditional(Object sender, EventUpdateCreditionalEventArgs e)
        {
            Credential.Domian = e.Domian;
            Credential.Password = e.Password;
            Credential.UserName = e.Name;
        }
        #endregion

        #region OptionsPages событие возникает при открытии редактирования Параметры
        private void OptionsPages(Outlook.PropertyPages Pages)
        {
            try
            {
                Pages.Add(new SattingsPage(sattings, PathConfig ), "investafinance");
            }
            catch (System.Exception e)
            {
                Debug.Assert(false, "ThisAddin.cs OptionsPages() :" + e.Message);
            }
        }
        #endregion

        #region Methods
        /// <summary>
        /// Looks up the window wrapper for a given window object
        /// </summary>
        /// <param name="window">An outlook inspector window</param>
        /// <returns></returns>
        internal static OutlookInspector FindOutlookInspector(object window)
        {
            foreach (OutlookInspector inspector in m_Windows)
            {
                if (inspector.Window == window)
                {
                    return inspector;
                }
            }
            return null;
        }

        /// <summary>
        /// Sets the default form for a folder
        /// </summary>
        /// <param name="defaultMessageClass"></param>
        /// <param name="defaultDisplayName"></param>
        /// <param name="folder"></param>
        private void SetDefaultFormForFolder(string defaultMessageClass,
            string defaultDisplayName, Outlook.Folder folder)
        {
            const string PR_DEF_POST_MSGCLASS =
                "http://schemas.microsoft.com/mapi/proptag/0x36E5001E";
            const string PR_DEF_POST_DISPLAYNAME =
                "http://schemas.microsoft.com/mapi/proptag/0x36E6001E";
            if (folder == null)
            {
                throw new ArgumentNullException(
                    "folder", "Parameter must contain a value.");
            }
            if (string.IsNullOrEmpty(defaultMessageClass))
            {
                throw new ArgumentNullException(
                    "defaultMessageClass",
                    "Parameter must contain a value.");
            }
            if (string.IsNullOrEmpty(defaultDisplayName))
            {
                throw new ArgumentNullException(
                    "defaultDisplayName",
                    "Parameter must contain a value.");
            }
            try
            {
                // Calling SetProperty sets the property without saving
                folder.PropertyAccessor.SetProperty(
                    PR_DEF_POST_DISPLAYNAME, defaultDisplayName);
                folder.PropertyAccessor.SetProperty(
                    PR_DEF_POST_MSGCLASS, defaultMessageClass);
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
        }

        #endregion

        #region Event Handlers
        private void Inspectors_NewInspector(Outlook.Inspector Inspector)
        {
            try
            {
                // Check to see if this is a new window 
                // we don't already track
                OutlookInspector existingWindow = FindOutlookInspector(Inspector);
                // If the m_Windows collection does not 
                // have a window for this Inspector,
                // we should add it to m_Windows
                if (existingWindow == null)
                {
                    OutlookInspector window = new OutlookInspector(Inspector);
                    window.Close += new EventHandler(WrappedWindow_Close);
                    m_Windows.Add(window);
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
        }
        void WrappedWindow_Close(object sender, EventArgs e)
        {
            OutlookInspector window = (OutlookInspector)sender;
            window.Close -= new EventHandler(WrappedWindow_Close);
            m_Windows.Remove(window);
        }
        #endregion

        #region VSTO generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InternalStartup()
        {
            this.Startup += new System.EventHandler(ThisAddIn_Startup);
            this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
        }

        #endregion
    }
}
